﻿/**
 * Copyright (c) 2008 Justin Etheredge http://www.codethinked.com
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Microsoft Public License (Ms-PL)
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/ms-pl.html
 * If redistributing this code, this entire header must remain intact.
 * 
 * Some of the code in this application has been taken 
 * from the following sources (all of which are licensed under
 * the Ms-PL):
 * Matt Warren's Blog: http://blogs.msdn.com/mattwar/
 * MSDN: http://msdn2.microsoft.com/en-us/library/bb546158.aspx
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using LinqToSimpleDB.HelperClasses;
using LinqToSimpleDB.Exceptions;


namespace LinqToSimpleDB
{
  internal class ItemFinder : HelperClasses.ExpressionVisitor
  {

    private Expression expression = null;
    private List<string> _itemNames = null;

    private bool foundAttributeReference = false;
    private bool foundNameReference = false;

    private List<string> ItemNames
    {
      get
      {
        if (_itemNames == null)
        {
          _itemNames = new List<string>();
        }
        return _itemNames;
      }
    }

    public ItemFinder(Expression exp)
    {
      this.expression = exp;
    }

    public List<string> GetItemNames()
    {
      this.Visit(expression);

      if (foundNameReference && foundAttributeReference)
      {
        throw new InvalidQueryException("References to names and to attributes cannot be mixed");
      }

      return this.ItemNames;
    }

    protected override Expression VisitBinary(BinaryExpression b)
    {
      if (ExpressionTreeHelpers.IsMemberEqualsValueExpression(b, typeof(SimpleDBItem), "Name"))
      {
        foundNameReference = true;
        string value = ExpressionTreeHelpers.GetValueFromEqualsExpression(b, typeof(SimpleDBItem), "Name");
        if (!String.IsNullOrEmpty(value))
        {
          this.ItemNames.Add(value);
        }
      }
      return base.VisitBinary(b);
    }

    protected override Expression VisitMethodCall(MethodCallExpression m)
    {
      if (m.Object != null && m.Object.Type == typeof(SimpleDBAttributeCollection) && String.Equals(m.Method.Name, "get_Item"))
      {
        foundAttributeReference = true;
      }
      return base.VisitMethodCall(m);
    }
  }
}
